﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Data;
using VAdvantage.Logging;
using VAdvantage.Utility;
using System.Collections.Generic;
using VAdvantage.DataBase;
using System.Text;

namespace VAdvantage.Model
{
    public class MLanguage : X_AD_Language
    {
        #region Private Variable
        //Logger
        // private static CLogger s_log = CLogger.getCLogger(MLanguage);
        //Locale
        //private Locale m_locale = null;
        //Date Format
        // private SimpleDateFormat m_dateFormat = null;
        #endregion

        /// <summary>
        ///Maintain Translation
        /// </summary>
        /// <param name="add">add if true add missing records - otherwise delete</param>
        /// <returns>number of records deleted/inserted</returns>
        public int Maintain(bool add)
        {
            String sql = "SELECT TableName FROM AD_Table WHERE TableName LIKE '%_Trl' ORDER BY 1";
            DataSet ds = null;
            int retNo = 0;
            try
            {
                ds = DB.ExecuteDataset(sql, null, null);
                for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                {
                    DataRow dr = ds.Tables[0].Rows[i];
                    if (add)
                    {
                        retNo += AddTable(dr[0].ToString());
                    }
                    else
                    {
                        retNo += DeleteTable(dr[0].ToString());
                    }

                }

                ds = null;
            }
            catch (Exception e)
            {
                log.Log(Level.SEVERE, sql, e);
            }
            return retNo;
        }

        /// <summary>
        ///Get Language Model from AD_Language
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="AD_Language_ID">language e.g. 191</param>
        /// <param name="trxName">trx</param>
        /// <returns>language or null</returns>
        public static MLanguage Get(Ctx ctx, String AD_Language, String trxName)
        {
            MLanguage lang = null;
            String sql = "SELECT * FROM AD_Language WHERE AD_Language='" + AD_Language + "'";
            DataSet ds = null;
            try
            {
                ds = DB.ExecuteDataset(sql, null, trxName);
                DataRow rs;
                for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                {
                    rs = ds.Tables[0].Rows[i];
                    lang = new MLanguage(ctx, rs, trxName);
                }
                ds = null;
            }
            catch (Exception ex)
            {
                log.Log(Level.SEVERE, sql, ex);
            }
            ds = null;
            return lang;
        }

        /// <summary>
        ///Get Language Model from AD_Language
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="AD_Language_ID">language e.g. 191</param>
        /// <param name="trxName">trx</param>
        /// <returns>language or null</returns>
        public static MLanguage Get(Ctx ctx, int AD_Language_ID, String trxName)
        {
            MLanguage lang = null;
            String sql = "SELECT * FROM AD_Language WHERE AD_Language_ID=" + AD_Language_ID;
            DataSet ds = null;
            try
            {
                ds = DB.ExecuteDataset(sql, null, trxName);
                DataRow rs;
                for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                {
                    rs = ds.Tables[0].Rows[i];
                    lang = new MLanguage(ctx, rs, trxName);
                }
                ds = null;
            }
            catch (Exception ex)
            {
                log.Log(Level.SEVERE, sql, ex);
            }
            ds = null;
            return lang;
        }

        /// <summary>
        ///	Get Language Model from Language
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="lang">language</param>
        /// <returns>language</returns>
        public static MLanguage Get(Ctx ctx, VAdvantage.Login.Language lang)
        {
            return Get(ctx, lang.GetAD_Language());
        }

        /// <summary>
        ///Get Language Model from AD_Language
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="AD_Language">language e.g. en_US</param>
        /// <returns>language or null</returns>
        public static MLanguage Get(Ctx ctx, string AD_Language)
        {
            MLanguage lang = null;
            String sql = "SELECT * FROM AD_Language WHERE AD_Language=" + AD_Language;


            return lang;
        }

        /// <summary>
        ///	Standard Constructor - NO NOT USE
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="AD_Language_ID">id</param>
        /// <param name="trxName">transaction</param>
        public MLanguage(Ctx ctx, int AD_Language_ID, String trxName)
            : base(ctx, AD_Language_ID, trxName)
        {
            //super (ctx, AD_Language_ID, trxName);
        }


        /// <summary>
        ///Load Constructor
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="rs">result set</param>
        /// <param name="trxName">transaction</param>
        public MLanguage(Ctx ctx, DataRow rs, String trxName)
            : base(ctx, rs, trxName)
        {
            //super(ctx, rs, trxName);
        }
        public MLanguage(Ctx ctx, IDataReader rs, String trxName)
            : base(ctx, rs, trxName)
        {
            //super(ctx, rs, trxName);
        }
        /// <summary>
        ///Add Translation to table
        /// </summary>
        /// <param name="tableName">table name</param>
        /// <returns>number of records inserted</returns>
        private int AddTable(String tableName)
        {
            String baseTable = tableName.Substring(0, tableName.Length - 4);
            String sql = "SELECT c.ColumnName "
                + "FROM AD_Column c"
                + " INNER JOIN AD_Table t ON (c.AD_Table_ID=t.AD_Table_ID) "
                + "WHERE t.TableName='" + baseTable
                + "'  AND c.IsTranslated='Y' AND c.IsActive='Y' "
                + "ORDER BY 1";
            List<String> columns = new List<string>(5);
            IDataReader dr = null;
            try
            {
                dr = DB.ExecuteReader(sql, null, null);
                //for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                while (dr.Read())
                {
                    //DataRow dr = ds.Tables[0].Rows[i];
                    //columns.Add(rs.getString(1));
                    //                    columns.Add(ds.Tables[0].Rows[i].ToString());
                    columns.Add(dr[0].ToString());
                }
                //ds = null;
                dr.Close();
            }
            catch (Exception e)
            {
                if (dr != null)
                {
                    dr.Close();
                }
                log.Log(Level.SEVERE, sql, e);
            }
            //	Columns
            //if (columns.size() == 0)
            if (columns.Count == 0)
            {
                log.Log(Level.SEVERE, "No Columns found for " + baseTable);
                throw new Exception("No Columns found for " + baseTable);
                return 0;
            }
            StringBuilder cols = new StringBuilder();
            for (int i = 0; i < columns.Count; i++)
            {
                cols.Append(",").Append(columns[i].ToString());
                //cols.Append(",").Append(columns[i].ToString());
            }

            //	Insert Statement
            int AD_User_ID = GetCtx().GetAD_User_ID();
            String keyColumn = baseTable + "_ID";
            String insert = "INSERT INTO " + tableName
                + "(AD_Language,IsTranslated, AD_Client_ID,AD_Org_ID, "
                + "CreatedBy,UpdatedBy, "
                + keyColumn + cols.ToString() + ") "
                + "SELECT '" + GetAD_Language() + "','N', AD_Client_ID,AD_Org_ID, "
                + AD_User_ID + "," + AD_User_ID + ", "
                + keyColumn + cols.ToString()
                + " FROM " + baseTable
                + " WHERE " + keyColumn + " NOT IN (SELECT " + keyColumn
                    + " FROM " + tableName
                    + " WHERE AD_Language='" + GetAD_Language() + "')";
            //	+ " WHERE (" + keyColumn + ",'" + getAD_Language()+ "') NOT IN (SELECT " 
            //		+ keyColumn + ",AD_Language FROM " + tableName + ")";

            int no = DataBase.DB.ExecuteQuery(insert.ToString(), null, Get_TrxName());
            return no;
        }

        /// <summary>
        ///Delete Translation
        /// </summary>
        /// <param name="tableName">table name</param>
        /// <returns>number of records deleted</returns>
        private int DeleteTable(String tableName)
        {
            String sql = "DELETE FROM " + tableName
                + " WHERE AD_Language='" + GetAD_Language() + "'";
            //int no = DB.executeUpdate(sql, Get_TrxName());
            int no = DataBase.DB.ExecuteQuery(sql, null, Get_TrxName());
            return no;
        }


        /***********************************************************************/

        /// <summary>
        ///	Create Language
        /// </summary>
        /// <param name="ctx">context</param>
        /// <param name="AD_Language">language code</param>
        /// <param name="Name">name</param>
        /// <param name="CountryCode">country code</param>
        /// <param name="LanguageISO">language code</param>
        /// <param name="trxName">transaction</param>
        //private MLanguage(Ctx ctx, String AD_Language, String Name,
        //    String CountryCode, String LanguageISO, String trxName)
        //    : base(ctx, 0, trxName)
        //{
        //    //super(ctx, 0, trxName);
        //    setAD_Language(AD_Language);	//	en_US
        //    setIsBaseLanguage(false);
        //    setIsSystemLanguage(false);
        //    setName(Name);
        //    setCountryCode(CountryCode);	//	US
        //    setLanguageISO(LanguageISO);	//	en
        //    String sql = "SELECT NVL(MAX(AD_Language_ID),0)+1 AS DefaultValue FROM AD_Language";
        //    setAD_Language_ID(DB.getSQLValue(trxName, sql));
        //}

        /* 
         /// <summary>
         ///	Maintain all active languages
         /// </summary>
         /// <param name="ctx">context</param>
         public static void maintain(Ctx ctx)
         {
             String sql = "SELECT * FROM AD_Language "
                 + "WHERE IsSystemLanguage='Y' AND IsBaseLanguage='N' AND IsActive='Y'";
             PreparedStatement pstmt = null;
             try
             {
                 pstmt = DB.prepareStatement(sql, null);
                 ResultSet rs = pstmt.executeQuery();
                 while (rs.next())
                 {
                     MLanguage language = new MLanguage(ctx, rs, null);
                     language.maintain(true);
                 }
                 rs.close();
                 pstmt.close();
                 pstmt = null;
             }
             catch (Exception e)
             {
                 s_log.log(Level.SEVERE, sql, e);
             }
             try
             {
                 if (pstmt != null)
                     pstmt.close();
                 pstmt = null;
             }
             catch (Exception e)
             {
                 pstmt = null;
             }
         }	//	maintain
         /// <summary>
         /// Load Languages (variants) with Language
         /// </summary>
         /// <param name="ctx">context</param>
         /// <param name="LanguageISO">language (2 letter) e.g. en</param>
         /// <returns>language</returns>
         public static MLanguage[] getWithLanguage(Ctx ctx, String LanguageISO)
         {
             ArrayList<MLanguage> list = new ArrayList<MLanguage>();
             String sql = "SELECT * FROM AD_Language WHERE LanguageISO=" + LanguageISO;
             PreparedStatement pstmt = null;
             try
             {
                 pstmt = DB.prepareStatement(sql, null);
                 pstmt.setString(1, LanguageISO);
                 ResultSet rs = pstmt.executeQuery();
                 while (rs.next())
                     list.add(new MLanguage(ctx, rs, null));
                 rs.close();
                 pstmt.close();
                 pstmt = null;
             }
             catch (Exception ex)
             {
                 s_log.log(Level.SEVERE, sql, ex);
             }
             try
             {
                 if (pstmt != null)
                     pstmt.close();
             }
             catch (Exception ex1)
             {
             }
             pstmt = null;
             //
             MLanguage[] languages = new MLanguage[list.size()];
             list.toArray(languages);
             return languages;
         }	//	get
         /// <summary>
         ///	String Representation
         /// </summary>
         /// <returns>info</returns>
         public String toString()
         {
             return "MLanguage[" + getAD_Language() + "-" + getName()
                 + ",Language=" + getLanguageISO() + ",Country=" + getCountryCode()
                 + "]";
         }
         /// <summary>
         ///Get Locale
         /// </summary>
         /// <returns>Locale</returns>
         public Locale getLocale()
         {
             if (m_locale == null)
                 m_locale = new Locale(getLanguageISO(), getCountryCode());
             return m_locale;
         }
         /// <summary>
         ///Get (Short) Date Format.
         ///The date format must parseable 
         ///i.e. leading zero for date and month
         /// </summary>
         /// <returns>date format MM/dd/yyyy - dd.MM.yyyy</returns>
         public SimpleDateFormat getDateFormat()
         {
             if (m_dateFormat != null)
                 return m_dateFormat;

             if (getDatePattern() != null)
             {
                 m_dateFormat = (SimpleDateFormat)DateFormat.getDateInstance
                     (DateFormat.SHORT, getLocale());
                 try
                 {
                     m_dateFormat.applyPattern(getDatePattern());
                 }
                 catch (Exception e)
                 {
                     //log.severe(getDatePattern() + " - " + e);
                     m_dateFormat = null;
                 }
             }

             if (m_dateFormat == null)
             {
                 //	Fix Locale Date format
                 m_dateFormat = (SimpleDateFormat)DateFormat.getDateInstance
                     (DateFormat.SHORT, getLocale());
                 String sFormat = m_dateFormat.toPattern();
                 //	some short formats have only one M and d (e.g. ths US)
                 if (sFormat.indexOf("MM") == -1 && sFormat.indexOf("dd") == -1)
                 {
                     String nFormat = "";
                     for (int i = 0; i < sFormat.length(); i++)
                     {
                         if (sFormat.charAt(i) == 'M')
                             nFormat += "MM";
                         else if (sFormat.charAt(i) == 'd')
                             nFormat += "dd";
                         else
                             nFormat += sFormat.charAt(i);
                     }
                     //	System.out.println(sFormat + " => " + nFormat);
                     m_dateFormat.applyPattern(nFormat);
                 }
                 //	Unknown short format => use JDBC
                 if (m_dateFormat.toPattern().length() != 8)
                     m_dateFormat.applyPattern("yyyy-MM-dd");

                 //	4 digit year
                 if (m_dateFormat.toPattern().indexOf("yyyy") == -1)
                 {
                     sFormat = m_dateFormat.toPattern();
                     String nFormat = "";
                     for (int i = 0; i < sFormat.length(); i++)
                     {
                         if (sFormat.charAt(i) == 'y')
                             nFormat += "yy";
                         else
                             nFormat += sFormat.charAt(i);
                     }
                     m_dateFormat.applyPattern(nFormat);
                 }
             }
             //
             m_dateFormat.setLenient(true);
             return m_dateFormat;
         }
         /// <summary>
         ///	Set AD_Language_ID
         /// </summary>
         private void setAD_Language_ID()
         {
             int AD_Language_ID = getAD_Language_ID();
             if (AD_Language_ID == 0)
             {
                 String sql = "SELECT NVL(MAX(AD_Language_ID), 999999) FROM AD_Language WHERE AD_Language_ID > 1000";
                 AD_Language_ID = DB.getSQLValue(get_TrxName(), sql);
                 setAD_Language_ID(AD_Language_ID + 1);
             }
         }
         /// <summary>
         ///Before Save
         /// </summary>
         /// <param name="newRecord">newRecord new</param>
         /// <returns>true/false</returns>
         protected bool beforeSave(boolean newRecord)
         {
             String dp = getDatePattern();
             if (is_ValueChanged("DatePattern") && dp != null && dp.length() > 0)
             {
                 if (dp.indexOf("MM") == -1)
                 {
                     log.saveError("Error", Msg.parseTranslation(getCtx(), "@Error@ @DatePattern@ - No Month (MM)"));
                     return false;
                 }
                 if (dp.indexOf("dd") == -1)
                 {
                     log.saveError("Error", Msg.parseTranslation(getCtx(), "@Error@ @DatePattern@ - No Day (dd)"));
                     return false;
                 }
                 if (dp.indexOf("yy") == -1)
                 {
                     log.saveError("Error", Msg.parseTranslation(getCtx(), "@Error@ @DatePattern@ - No Year (yy)"));
                     return false;
                 }

                 m_dateFormat = (SimpleDateFormat)DateFormat.getDateInstance
                     (DateFormat.SHORT, getLocale());
                 try
                 {
                     m_dateFormat.applyPattern(dp);
                 }
                 catch (Exception e)
                 {
                     log.saveError("Error", Msg.parseTranslation(getCtx(), "@Error@ @DatePattern@ - " + e.getMessage()));
                     m_dateFormat = null;
                     return false;
                 }
             }
             if (newRecord)
                 setAD_Language_ID();
             return true;
         }
         /// <summary>
         ///AfterSave
         /// </summary>
         /// <param name="newRecord">new</param>
         /// <param name="success">success</param>
         /// <returns>true if saved</returns>
         protected bool afterSave(bool newRecord, bool success)
         {
             int no = TranslationTable.getActiveLanguages(true);
             //log.fine("Active Languages=" + no);
             return true;
         }
         //	deleteTable
         //	addTable
         /// <summary>
         ///	Setup
         /// </summary>
         /// <param name="args">args</param>
         public static void main(String[] args)
         {
             

             //System.out.println(MLanguage.get(Env.getCtx(), "de_DE"));
             //System.out.println(MLanguage.get(Env.getCtx(), "en_US"));

             /**
             Locale[] locales = Locale.getAvailableLocales();
             for (int i = 0; i < locales.length; i++)
             {
                 Locale loc = locales[i];
                 if (loc.getVariant() != null && loc.getVariant().length() != 0)
                     continue;
                 if (loc.getCountry() != null && loc.getCountry().length() != 0)
                     continue;

                 System.out.println(loc.toString()
                     + " - " + loc.getDisplayName()
                     + " + " + loc.getCountry()
                     + " + " + loc.getLanguage()
                 );
                 MLanguage lang = new MLanguage (Env.getCtx(), loc.toString(),
                     loc.getDisplayName(), loc.getCountry(), loc.getLanguage());
                 lang.save();
                 System.out.println(lang);
             }
         }	
         */
    }
}
